package com.yunkeji.common.utils.piggy;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.piggy.settlement.sdk.client.sign.PiggySignApiClient;
import com.piggy.settlement.sdk.client.v2.basics.PiggyOpenBasicsClient;
import com.piggy.settlement.sdk.client.labor.singlewithdraw.PiggyLaborSingleWithdrawalApiClient;
import com.piggy.settlement.sdk.util.v2.PiggyOpenBasicsAesUtil;
import com.piggy.settlement.sdk.vo.sign.PiggySignResultVo;
import com.piggy.settlement.sdk.vo.sign.PiggySignVo;
import com.piggy.settlement.sdk.vo.v2.basics.PiggyBasicsVo;
import com.piggy.settlement.sdk.vo.v2.singlewithdraw.PiggySingleWithdrawV2Vo;
import com.yunkeji.common.config.PiggyProperties;
import com.yunkeji.common.enums.app.SettleTypeEnums;
import com.yunkeji.common.exception.AppServiceException;
import com.yunkeji.common.helper.LoginHelper;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 小猪结算
 *
 * @author 老张
 */
@Slf4j
public class PiggyUtils {

    private static PiggyProperties PIG_CONFIG = SpringUtil.getBean(PiggyProperties.class);

    /**
     * 发起提现
     *
     * @author 老张
     */
    public static String singleSubmit(
            String empName,
            String empPhone,
            String licenseId,
            SettleTypeEnums settleType,
            String payAccount,
            BigDecimal payAmount) {

        PiggyLaborSingleWithdrawalApiClient v2Client =
            PiggyLaborSingleWithdrawalApiClient.getInstanse(
                        PIG_CONFIG.getSecret(), PIG_CONFIG.getDomain());
        int i = RandomUtil.randomInt(100000, 900000);
        String appkey  = settleType.equals(SettleTypeEnums.银行卡) ? PIG_CONFIG.getBankAppKey() : PIG_CONFIG.getAlipayAppKey();
        String outerTradeNo = "P" + new Date().getTime() + i;
        PiggySingleWithdrawV2Vo build =
                PiggySingleWithdrawV2Vo.builder()
                        .appKey(appkey)
                        .bizAESContent(
                                PiggyOpenBasicsAesUtil.produceAesData(
                                        PIG_CONFIG.getSecret(),
                                        PIG_CONFIG.getIvStr(),
                                        PiggySingleWithdrawV2Vo.SingleWithdrawV2Vo.builder()
                                                .notifyUrl(PIG_CONFIG.getPiggyPayCallBack())
                                                // TODO 需要灵活配置
                                                .taxFundId(
                                                        settleType.equals(SettleTypeEnums.银行卡)
                                                                ? PIG_CONFIG.getBankTaxFundId()
                                                                : PIG_CONFIG.getAlipayTaxFundId())
                                                .month(
                                                        DateUtil.format(
                                                                new Date(),
                                                                DatePattern.NORM_MONTH_PATTERN))
                                                .outerTradeNo(outerTradeNo)
                                                .empName(empName)
                                                .empPhone(empPhone)
                                                .licenseId(licenseId)
                                                .licenseType("ID_CARD")
                                                .settleType(settleType.getCode())
                                                .payAccount(payAccount)
                                                .positionName(PIG_CONFIG.getPosition())
                                                .payAmount(payAmount.doubleValue())
                                                .build()))
                        .build();
        JSONObject res = v2Client.singleSubmit(build);
        log.info(
                "小猪单笔提现上报,appkey:{},empName:{}.empPhone:{},licenseId:{},settleType:{},payAccount:{},payAmount:{},res:{}",
                appkey,
                empName,
                empPhone,
                licenseId,
                settleType,
                payAccount,
                payAmount,
                res.toStringPretty());
        String isSuccess = res.getStr("isSuccess");
        if ("T".equals(isSuccess)) {
            return res.getJSONObject("data").getStr("outerTradeNo");
        }

        return "";
    }

    public static boolean payConfirm(SettleTypeEnums settleType, String outerTradeNo) {
        PiggyLaborSingleWithdrawalApiClient v2Client =
            PiggyLaborSingleWithdrawalApiClient.getInstanse(
                PIG_CONFIG.getSecret(), PIG_CONFIG.getDomain());
        String appkey  = settleType.equals(SettleTypeEnums.银行卡) ? PIG_CONFIG.getBankAppKey() : PIG_CONFIG.getAlipayAppKey();

        PiggySingleWithdrawV2Vo payBuild =
            PiggySingleWithdrawV2Vo.builder()
                .appKey(appkey)
                .bizAESContent(
                    PiggyOpenBasicsAesUtil.produceAesData(
                        PIG_CONFIG.getSecret(),
                        PIG_CONFIG.getIvStr(),
                        PiggySingleWithdrawV2Vo.SingleWithdrawV2Vo.builder()
                            .outerTradeNo(outerTradeNo)
                            .build()))
                .outerTradeNo(outerTradeNo)
                .build();
        log.info(
            "小猪单笔确认支付,param:{}",
            payBuild);
        JSONObject payRes = v2Client.payConfirm(payBuild);
        log.info(
            "小猪单笔确认支付,res:{}",
            payRes.toStringPretty());

        return "T".equals(payRes.getStr("isSuccess"));
    }

    /**
     * 支付回调参数解密
     *
     * @author 老张
     */
    public static JSONObject analysisAesDataDev(String bizAESContent) {
        try {
            String s =
                    PiggyOpenBasicsAesUtil.analysisAesDataDev(
                            PIG_CONFIG.getSecret(), PIG_CONFIG.getIvStr(), bizAESContent);
            return JSONUtil.parseObj(s);
        } catch (Exception e) {
            log.error("Aes 解密失败", e);
            throw AppServiceException.paramException("参数解密错误");
        }
    }

    /**
     * 获取资金池汇总余额查询
     *
     * @author 老张
     */
    public static BigDecimal getCashPooling(int type) {
        String appKey  = (type == SettleTypeEnums.银行卡.getType()) ? PIG_CONFIG.getBankAppKey() : PIG_CONFIG.getAlipayAppKey();
        PiggyOpenBasicsClient piggySignApiClient =
                PiggyOpenBasicsClient.getInstanse(PIG_CONFIG.getSecret(), PIG_CONFIG.getDomain());
        log.info("查询剩余余额:{}, {}, {}", appKey, PIG_CONFIG.getSecret(), PIG_CONFIG.getDomain());
        JSONObject cashPooling =
                piggySignApiClient.getCashPooling(
                        PiggyBasicsVo.builder().appKey(appKey).build());
        log.info("查询剩余余额:{}", cashPooling.toStringPretty());
        if ("T".equals(cashPooling.getStr("isSuccess"))) {
            return cashPooling.getJSONObject("data").getBigDecimal("availableBalance");
        } else {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 获取电签状态
     *
     * @author 老张
     */
    public static boolean needToSign(String idCardNo, String userName) {
        PiggySignApiClient piggySignApiClient =
                PiggySignApiClient.getInstanse(PIG_CONFIG.getSecret(), PIG_CONFIG.getDomain());
        try {
            JSONObject jsonObject =
                    piggySignApiClient.getSignStatus(
                            PiggySignResultVo.builder()
                                    .appKey(PIG_CONFIG.getAlipayAppKey())
                                    .idCardNo(idCardNo)
                                    .userName(userName)
                                    .position(PIG_CONFIG.getPosition())
                                    .build());
            log.info(
                    "查询是否需要电签,card:{}.name:{},res:{}",
                    idCardNo,
                    userName,
                    jsonObject.toStringPretty());
            //            {
            //                "code": 0,
            //                "msg": "有待签合同",
            //                "errorCode": null,
            //                "data": null
            //            }
            //            {
            //                "code": 0,
            //                "msg": "success",
            //                "errorCode": null,
            //                "data": "合同签署完毕"
            //            }
            return jsonObject.getStr("data") == null;
        } catch (Exception e) {
            log.error("电签状态异常", e);
            return true;
        }
    }

    /**
     * 获取电签URL {"code":0,"msg":"success","errorCode":null,"data":"https://suat.xzsz.ltd/YSeF6mSp"}
     *
     * @author 老张
     */
    public static String getSignUrl(
            String bankAccount, String idCardNo, String mobile, String userName) {
        PiggySignApiClient piggySignApiClient =
                PiggySignApiClient.getInstanse(PIG_CONFIG.getSecret(), PIG_CONFIG.getDomain());
        try {
            JSONObject jsonObject =
                    piggySignApiClient.getSignUrl(
                            PiggySignVo.builder()
                                    .appKey(PIG_CONFIG.getAlipayAppKey())
                                    .bankAccount(bankAccount)
                                    .customParams(
                                            JSONUtil.createObj()
                                                    .set("uid", LoginHelper.getUserId())
                                                    .toString())
                                    .idCardNo(idCardNo)
                                    .jumpPage(PIG_CONFIG.getJumpPage())
                                    .mobile(mobile)
                                    .notifyUrl(PIG_CONFIG.getPiggySignCallBack())
                                    .position(PIG_CONFIG.getPosition())
                                    .userName(userName)
                                    .build());
            log.info(
                    "bankAccount:{}.idCardNo:{},mobile:{},userName:{},res:{}",
                    bankAccount,
                    idCardNo,
                    mobile,
                    userName,
                    jsonObject.toStringPretty());
            if (0 != jsonObject.getInt("code")) {
                throw AppServiceException.paramException(jsonObject.getStr("msg"));
            }
            return jsonObject.getStr("data");
        } catch (Exception e) {
            log.error("获取电签链接异常", e);
            return "";
        }
    }
}
